home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C="$Id: passwd.c,v 1.5 1994/05/02 19:52:55 jraja Exp $";
- /*
- * passwd.c -- change password
- *
- * Author: ppessi <Pekka.Pessi@hut.fi>
- *
- * Copyright © 1994 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
- * Helsinki University of Technology, Finland.
- *
- * Created : Tue Jan 11 14:06:41 1994 ppessi
- * Last modified: Sun Feb 27 03:45:36 1994 ppessi
- *
- */
-
- #include "passwd_rev.h"
-
- static const char version[] = VERSTAG " "
- "Copyright © 1994 AmiTCP/IP Group, <amitcp-group@hut.fi>\n"
- "Helsinki University of Technology, Finland.\n";
-
- /****** utilities/passwd *****************************************************
-
- NAME
- passwd - modify a user's password
-
- VERSION
- $Id: passwd.c,v 1.5 1994/05/02 19:52:55 jraja Exp $
-
- SYNOPSIS
- passwd [user]
-
- FUNCTION
-
- Passwd changes the user's password. First, the user is prompted for
- their current password. If the current password is correctly typed, a
- new password is requested. The new password must be entered twice to
- avoid typing errors.
-
- The new password should be at least six characters long and not purely
- alphabetic. Its total length must be less than _PASSWORD_LEN
- (currently 128 characters). Numbers, upper case letters and meta
- characters are en couraged.
-
- Once the password has been verified, passwd communicates the new
- password information to the netinfo.device.
-
- The super-user is not required to provide a user's current password.
-
- FILES
-
- SEE ALSO
- login
-
- Robert Morris, and Ken Thompson, UNIX password security.
-
- HISTORY
- A passwd command appeared in Version 6 AT&T UNIX.
-
- ****************************************************************************
- */
-
- #if defined(__SASC)
- extern struct ExecBase *SysBase;
- #include <pragmas/exec_sysbase_pragmas.h>
- #include <clib/exec_protos.h>
- #include <proto/usergroup.h>
- #include <proto/dos.h>
- /* Disable ^C signaling */
- void __regargs __chkabort(void) {}
- #else
- #include <clib/exec_protos.h>
- #include <clib/usergroup_protos.h>
- #include <clib/dos_protos.h>
- #endif
-
- #include <dos/rdargs.h>
-
- #include <sys/time.h>
- #include <sys/param.h>
-
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
-
- #include <pwd.h>
- #include <grp.h>
- #include <unistd.h>
- #include <errno.h>
-
- #include "config.h"
-
- #include <bsdsocket.h>
-
- BPTR Stdin, Stdout, Stderr;
- APTR WinPtr = NULL;
- struct RDArgs *rdargs = NULL;
- struct MsgPort *port = NULL;
- struct NetInfoReq *req = NULL;
- short device_is_open = 0;
-
- static void resume_amiga_stdio(void)
- {
- struct Process* me = (struct Process *)FindTask(NULL);
- me->pr_WindowPtr = WinPtr;
-
- if (rdargs)
- FreeArgs(rdargs);
- rdargs = NULL;
-
- if (device_is_open)
- CloseDevice((struct IORequest *)req);
- if (req)
- DeleteIORequest((struct IORequest *)req);
- if (port)
- DeleteMsgPort(port);
- }
-
- static void startup_amiga_stdio(void)
- {
- struct Process* me = (struct Process *)FindTask(NULL);
- Stdin = me -> pr_CIS;
- Stdout = me -> pr_COS;
- Stderr = (me -> pr_CES ? me -> pr_CES : Stdout);
-
- /* Remove requesters */
- WinPtr = me->pr_WindowPtr;
- me->pr_WindowPtr = (void *)-1L;
- atexit(resume_amiga_stdio);
- }
-
- int local_passwd(char *uname);
- char *getnewpasswd(struct passwd *pw);
- void pw_update(struct passwd *pw);
-
- void main(void)
- {
- const char *template =
- "USERNAME";
- struct {
- STRPTR a_name;
- } args[1] = { 0 };
-
- startup_amiga_stdio();
-
- rdargs = ReadArgs((STRPTR)template, (LONG *)args, NULL);
- if (!rdargs) {
- PrintFault(IoErr(), "passwd");
- exit(RETURN_ERROR);
- }
-
- if (args->a_name) {
- exit(local_passwd(args->a_name));
- } else {
- char *uname = getlogin();
- if (uname)
- exit(local_passwd(uname));
-
- FPrintf(Stderr, "passwd: no user");
- exit(RETURN_ERROR);
- }
- }
-
- static uid_t uid;
-
- int local_passwd(char *uname)
- {
- struct passwd *pw;
-
- if (!(pw = getpwnam(uname))) {
- (void)FPrintf(Stderr, "passwd: unknown user %s.\n", uname);
- exit(RETURN_ERROR);
- }
-
- uid = getuid();
- if (uid && uid != pw->pw_uid) {
- (void)FPrintf(Stderr, "passwd: %s\n", ug_StrError(EACCES));
- exit(RETURN_ERROR);
- }
-
- /*
- * Get the new password.
- */
- pw->pw_passwd = getnewpasswd(pw);
-
- pw_update(pw);
- return 0;
- }
-
- char *getnewpasswd(struct passwd *pw)
- {
- register char *p, *t;
- int tries;
- char buf[_PASSWORD_LEN+1], salt[16];
-
- (void)Printf("Changing password for %s.\n", pw->pw_name);
-
- if (uid && pw->pw_passwd && pw->pw_passwd[0] &&
- strcmp(crypt(getpass("Old password:"), pw->pw_passwd),
- pw->pw_passwd)) {
- (void)FPrintf(Stderr, "passwd: %s\n", ug_StrError(EACCES));
- exit(RETURN_ERROR);
- }
-
- for (buf[0] = '\0', tries = 0;;) {
- p = getpass("New password:");
- if (!*p) {
- (void)PutStr("Password unchanged.\n");
- exit(RETURN_ERROR);
- }
- if (strlen(p) <= 5 && (uid != 0 || ++tries < 2)) {
- (void)PutStr("Please enter a longer password.\n");
- continue;
- }
- for (t = p; *t && islower(*t); ++t);
- if (!*t && (uid != 0 || ++tries < 2)) {
- (void)PutStr("Please don't use an all-lower case password.\n"
- "Unusual capitalization, control characters or "
- "digits are suggested.\n");
- continue;
- }
- (void)strncpy(buf, p, _PASSWORD_LEN);
- if (!strcmp(buf, getpass("Retype new password:")))
- break;
- (void)Printf("Mismatch; try again, EOF to quit.\n");
- }
-
- strncpy(salt, pw->pw_passwd, sizeof(salt));
- salt[8] = '\0';
- ug_GetSalt(pw, salt, sizeof(salt));
-
- return(crypt(buf, salt));
- }
-
- #include <devices/netinfo.h>
-
- void pw_update(struct passwd *pw)
- {
- if (port = CreateMsgPort())
- req = CreateIORequest(port, sizeof(*req));
- if (!port || !req) {
- PrintFault(ERROR_NO_FREE_STORE, "CreateIORequest");
- exit(RETURN_FAIL);
- }
-
- if (OpenDevice(NETINFONAME, NETINFO_PASSWD_UNIT,
- (struct IORequest *)req, 0L)) {
- Printf("%s: %s\n", NETINFONAME, ug_StrError(req->io_Error));
- exit(RETURN_FAIL);
- }
-
- device_is_open = 1;
-
- req->io_Data = pw;
- req->io_Command = CMD_WRITE;
- DoIO(req);
- if (req->io_Error) {
- Printf("%s (%s): %s\n", NETINFONAME, "CMD_WRITE",
- ug_StrError(req->io_Error));
- exit(RETURN_FAIL);
- }
-
- req->io_Command = CMD_UPDATE;
- DoIO(req);
- if (req->io_Error) {
- Printf("%s (%s): %s\n", NETINFONAME, "CMD_UPDATE",
- ug_StrError(req->io_Error));
- exit(RETURN_FAIL);
- }
- }
-